'use strict';

const pkdDir = require('pkg-dir').sync
const path = require('path');
const pathExists = require('path-exists').sync;
const fse = require('fs-extra');

const { IsObject } = require('@imooc-my-test1/utils')
const formatPath = require('@imooc-my-test1/format-path')
const { getDefaultRegistryUrl, getNpmLatestVersion  } = require('@imooc-my-test1/get-npm-info')

const log = require('@imooc-my-test1/log')
const npminstall = require('npminstall');

class Package {
  constructor(options) {
    if(!options ) {
      throw new Error('必须传入options')
    } 
    if(!IsObject(options)) {
      throw new Error('传入的options必须是对象')
    }
    // 参数,不传这个package的路径，就说明它不是使用的本地的包
    this.targetPath = options.targetPath;
    // storePath 缓存到本地的路径
    this.storePath = options.storePath;
    // packageName 包名
    this.packageName = options.packageName;
    // packageVersion 包版本
    this.packageNameVersion = options.packageNameVersion;

    this.cacheFilePathPrefix = this.packageName.replace('/', '_');

  }

  async prepare() {
    if(this.storePath && !pathExists(this.storePath)) {
      console.log(fse.mkdirSync)

      fse.mkdirsSync(this.storePath)
    }
    if(this.packageNameVersion === 'latest') {
      this.packageNameVersion = await getNpmLatestVersion(this.packageName)
    }

  }

  get cacheFilePath() {
    return path.resolve(this.storePath, `_${this.cacheFilePathPrefix}@${this.packageNameVersion}@${this.packageName}`)
  }

  get nowFileVersion() {
    return require(path.resolve(this.cacheFilePath, 'package.json')).version 
  }

  async exists() {
    if(this.storePath) {
      await this.prepare()
      return pathExists(this.cacheFilePath)
    } else {
      return pathExists(this.targetPath)
    }
  }
  async install() {
    await this.prepare()
    return npminstall({
      root: this.targetPath,
      storeDir: this.storePath,
      registry: getDefaultRegistryUrl(),
      pkgs: [
        { 
          name: this.packageName,
          version: this.packageNameVersion
        }
      ]
      
    })
  }
  async update() {
    await this.prepare()
    // 1. 获取最新的npm对应的版本号
    const latestVersion = await getNpmLatestVersion(this.packageName);
    // 2. 查询最新版本号对应的路径是否存在
    if(latestVersion !== this.nowFileVersion) {
    // 3. 如果不存在，则直接安装最新版本
      await npminstall({
        root: this.targetPath,
        storeDir: this.storePath,
        registry: getDefaultRegistryUrl(),
        pkgs: [
          { 
            name: this.packageName,
            version: latestVersion
          }
        ]
        
      })
    }
    this.packageNameVersion = latestVersion;
  }
  // 获取入口文件的路径
  getRootFilePath() {
    function _getPath(targetPath) {
      const targetPkgDir = pkdDir(targetPath)
      if(targetPkgDir) {
        // 2. 获取package.json
        const pkgFile = require(path.resolve(targetPkgDir, 'package.json'));
        // 3. 寻找main
        if(pkgFile && pkgFile.main) {
        // 4. 路径的兼容
          return formatPath(path.resolve(targetPkgDir, pkgFile.main))
        }
      }
    }
    if(this.storePath) {
      // 1. 获取package.json所在的目录
     return _getPath(this.cacheFilePath)
    } else {
     return _getPath(this.targetPath)
    }

    return null
  }

}

module.exports = Package;
